﻿using System.Text.Json;
using System.Text.Json.Serialization;

namespace IMClient.Model.Message;

/// <summary>
/// 消息类型转换器
/// 由于SystemMessage是抽象类，无法直接使用，所以需要使用JsonConverter进行转换
/// 在将Json反序列化成SystemMessage时，根据SystemType字段进行反序列化
/// </summary>

[JsonDerivedType(typeof(AddFriendRequest), typeDiscriminator: "AddFriendRequest")]
[JsonDerivedType(typeof(AddFriendResponse), typeDiscriminator: "AddFriendResponse")]
[JsonDerivedType(typeof(JoinGroupRequest), typeDiscriminator: "JoinGroupRequest")]
[JsonDerivedType(typeof(JoinGroupResponse), typeDiscriminator: "JoinGroupResponse")]
[JsonDerivedType(typeof(InitialGroupNotification), typeDiscriminator: "InitialGroupNotification")]
[JsonDerivedType(typeof(GroupNameUpdateNotification), typeDiscriminator: "GroupNameUpdateNotification")]
[JsonDerivedType(typeof(GroupAvatarUpdateNotification), typeDiscriminator: "GroupAvatarUpdateNotification")]
public class SystemMessageJsonDerivedTypeConverter : JsonConverter<SystemMessage>
{
    public override SystemMessage Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        using (JsonDocument document = JsonDocument.ParseValue(ref reader))
        {
            JsonElement root = document.RootElement;
            string systemType = (root.TryGetProperty("SystemType", out JsonElement property) ? property.GetString() : null) ?? throw new InvalidOperationException();

            switch (systemType)
            {
                case "AddFriendRequest":
                    return JsonSerializer.Deserialize<AddFriendRequest>(root.GetRawText(), options) ?? throw new InvalidOperationException();
                case "AddFriendResponse":
                    return JsonSerializer.Deserialize<AddFriendResponse>(root.GetRawText(), options) ?? throw new
                        InvalidOperationException();
                case "JoinGroupRequest":
                    return JsonSerializer.Deserialize<JoinGroupRequest>(root.GetRawText(), options) ?? throw new InvalidOperationException();
                case "JoinGroupResponse":
                    return JsonSerializer.Deserialize<JoinGroupResponse>(root.GetRawText(), options) ?? throw new InvalidOperationException();
                case "InitialGroupNotification":
                    return JsonSerializer.Deserialize<InitialGroupNotification>(root.GetRawText(), options) ?? throw new InvalidOperationException();
                case "GroupNameUpdateNotification":
                    return JsonSerializer.Deserialize<GroupNameUpdateNotification>(root.GetRawText(), options) ?? throw new InvalidOperationException();
                case "GroupAvatarUpdateNotification":
                    return JsonSerializer.Deserialize<GroupAvatarUpdateNotification>(root.GetRawText(), options) ?? throw new InvalidOperationException();
                default:
                    throw new JsonException($"Unknown SystemType: {systemType}");
            }
        }
    }
    
    public override void Write(Utf8JsonWriter writer, SystemMessage value, JsonSerializerOptions options)
    {
        JsonSerializer.Serialize(writer, value, value.GetType(), options);
    }
}